using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Linq;
using Newtonsoft.Json;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.FAS.Runtime.DataAccess.Common;

namespace T.FAS.Runtime.DataAccess.Engine
{
    public class QueryPlanSortHelper
    {
        private const string UserDefinedColumn = "__UserDefineColumns";
        /// <summary>
        /// Group结构化的查询条件
        /// </summary>
        public List<Sort> Sorts = default;
        private DataQuery _dataQuery = default;

        public QueryPlanSortHelper(string sortJson, DataQuery dataQuery)
        { 
            if (!string.IsNullOrEmpty(sortJson))
            {
                try
                {
                    this.Sorts = JsonConvert.DeserializeObject<List<Sort>>(sortJson);
                    this._dataQuery = dataQuery;
                }
                catch (Exception e)
                {
                    throw new FasException(DataAccessErrorCode.DataQuery.QueryPlanError, string.Format(CommonStringClassEngine.QueryPlanSortHelper_,sortJson,dataQuery?.ID), e);
                }
            }
        }

        public List<AdvancedSort> GetAdvancedSorts()
        {
            List<AdvancedSort> advancedSorts = new List<AdvancedSort>();
            foreach (var sort in Sorts)
            {
                //如果为自定义排序列
                if (string.IsNullOrEmpty(sort.SortSource) || sort.SortSource == UserDefinedColumn)
                {
                    var userDefinedCol = _dataQuery.DataQueryColumns.FirstOrDefault(col => col.Alias == sort.SortColumn && col.ColumnType == ColumnType.Express);
                    if (userDefinedCol == null)
                    {
                        throw new FasException(DataAccessErrorCode.DataQuery.QueryPlanError, string.Format(CommonStringClassEngine.QueryPlanSortHelper_GetAdvancedSorts,sort.SortColumn,_dataQuery.Code));
                    }
                    string sortExpression = string.IsNullOrEmpty(userDefinedCol.ColumnExpressionJson)
                                            ? userDefinedCol.ColumnExpression
                                            : userDefinedCol.ColumnExpressionJson;
                    if (!string.IsNullOrEmpty(sortExpression))
                    {
                        advancedSorts.Add(new AdvancedSort
                        {
                            Sort = sort,
                            IsUserDefinedColumnSort = true,
                            UserDefinedSortColumn = userDefinedCol,
                            UserDefinedSortExpression = sortExpression
                        });
                    }
                }
                else
                {
                    DataQuerySource source = GetQuerySource(sort.SortSource);
                    DataQueryColumn sortColumn = _dataQuery.DataQueryColumns.FirstOrDefault(col => col.DataQuerySourceID == source.ID && col.Alias == sort.SortColumn);
                    string realSortColumnName = sort.SortColumn;
                    if (!string.IsNullOrEmpty(sortColumn?.DataColumn?.ColumnName))
                    {
                        realSortColumnName = sortColumn.DataColumn.ColumnName;
                    }
                    else if (!string.IsNullOrEmpty(sortColumn?.Name))
                    {
                        realSortColumnName = sortColumn.Name;
                    }
                    advancedSorts.Add(new AdvancedSort
                    {
                        Sort = sort,
                        SortColumnName = realSortColumnName,
                        DataQuerySource = source
                    });
                }
            }
            return advancedSorts;
        }

        private DataQuerySource GetQuerySource(string dataQuerySourceID)
        {
            var source = _dataQuery.DataQuerySources.FirstOrDefault(s => s.ID == dataQuerySourceID);
            if (source == null)
                throw new FasException(DataAccessErrorCode.DataQuery.QueryPlanError, string.Format(CommonStringClassEngine.QueryPlanSortHelper_GetQuerySource,dataQuerySourceID,_dataQuery.Code));
            return source;
        }

    }

    public class AdvancedSort
    {
        public bool IsUserDefinedColumnSort { get; set; } = false;
        public Sort Sort { get; set; }
        public string SortColumnName { get; set; }
        public DataQuerySource DataQuerySource { get; set; }
        public DataQueryColumn UserDefinedSortColumn { get; set; }
        public string UserDefinedSortExpression { get; set; }
    }
}
